/*
状态表示：f[i][j][k]
    所有A[1,i], B[1, j]的不包含字符串C的，和C匹配的最大前后缀长度为k的公共子序列的集合

    集合中公共子序列的最大长度

状态计算
    1.不含A[i], 不含B[j]
        f[i-1][j-1][k]
    2.不含A[i], 含B[j]
        包含第一种，子集覆盖 f[i-1][j][k]
    3.含A[i], 不含B[j]
        包含第一种，子集覆盖 f[i][j-1][k]
    4.含A[i], 含B[j]
        f[i-1][j-1][X]+1 k的前驱不唯一，后继唯一
*/
#define quickread
#ifdef quickread
#include <cstdio> 
template <typename T>
inline void read(T& x)
{
    int c=getchar(), f=1; x=0;
    while(c<'0'||'9'<c) {if(c=='-') f=-1; c=getchar();}
    while('0'<=c&&c<='9') 
        x=(x<<3)+(x<<1)+c-'0', c=getchar();
    x*=f;
}
template <typename T>
inline void quickwrite(T x)
{
    if(x>=10) quickwrite(x/10);
    putchar(x%10+'0');
}
#else 
#include <iostream>
#endif
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
#define DEBUG
const int N=110;

int n, m, l;
char a[N], b[N], c[N];
int ne[N], f[N][N][N];

struct Node
{
    int i, j, k;
}g[N][N][N]; //由哪个状态转移而来

//{ti, tj, tk} <- {fi, fj, fk}
void update(int ti, int tj, int tk, int fi, int fj, int fk, int v)
{
    if(f[ti][tj][tk]<v)
    {
        f[ti][tj][tk]=v;
        g[ti][tj][tk]={fi, fj, fk};
    }
}

void init()
{
    scanf("%s%s%s", a+1, b+1, c+1);
    n=strlen(a+1), m=strlen(b+1), l=strlen(c+1);
    // next[]
    for(int i=2, j=0; i<=l; i++)
    {
        while(j&&c[i]!=c[j+1]) j=ne[j];
        if(c[i]==c[j+1]) j++;
        ne[i]=j;
    }

}

void solve()
{
    init();

    memset(f, -1, sizeof f);
    f[0][0][0]=0;

    int res=0, ri, rj, rk; //最大长度 答案的当前状态
    
    //匹配
    for(int i=0; i<=n; i++)
        for(int j=0; j<=m; j++)
            for(int k=0; k<l; k++) //不能完全匹配
            {
                int v=f[i][j][k];
                if(v==-1) continue;

                update(i+1, j, k, i, j, k, v);
                update(i, j+1, k, i, j, k, v);

                if(a[i+1]==b[j+1]) //可以同时取
                {
                    int p=k;
                    while(p&&a[i+1]!=c[p+1]) p=ne[p]; //新加入的字符!=
                    if(a[i+1]==c[p+1]) p++;
                    update(i+1, j+1, p, i, j, k, v+1);
                }

                if(v>res)
                {
                    res=v;
                    ri=i, rj=j, rk=k;
                }
            }
    if(!res) puts("0");
    else
    {
        string str;
        while(ri||rj||rk)
        {
            auto t=g[ri][rj][rk];
            if(t.i<ri&&t.j<rj) str+=a[ri];
            ri=t.i, rj=t.j, rk=t.k;
        }
        reverse(str.begin(), str.end());

        printf("%s\n", str.c_str());
    }
}

// #undef DEBUG
signed main()
{
    #ifdef DEBUG
        freopen("../in.txt", "r", stdin);
        freopen("../out.txt", "w", stdout);
    #endif
    #ifndef quickread
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    #endif

    int T=1; //scanf("%d", &T);
    while(T--) 
    {
        solve();
    }
    return 0;
}